package com.cqfae.deploycentral.app.job;

import com.cqfae.deploycentral.api.utils.IdGenerator;
import com.cqfae.deploycentral.app.base.BaseConstants;
import com.cqfae.deploycentral.app.config.JiraIssues;
import com.cqfae.deploycentral.app.dao.entity.ReportInfo;
import com.cqfae.deploycentral.app.dao.entity.ReportJira;
import com.cqfae.deploycentral.app.dao.entity.ReportTestLink;
import com.cqfae.deploycentral.app.dao.mapper.ReportInfoMapper;
import com.cqfae.deploycentral.app.dao.mapper.ReportJiraMapper;
import com.cqfae.deploycentral.app.dao.mapper.ReportTestLinkMapper;
import com.cqfae.deploycentral.app.services.JiraService;
import com.cqfae.deploycentral.app.utils.GsonUtils;
import com.cqfae.deploycentral.app.utils.QuartzUtil;
import com.cqfae.deploycentral.app.web.response.JiraInfo;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import tk.mybatis.mapper.entity.Example;

import java.text.MessageFormat;
import java.util.*;

/**
 * Created by JIANGLU009 on 2017/12/1.
 */

public class JiraJob implements Job {

    private static Logger logger = LoggerFactory.getLogger(JiraJob.class);

    private String sqlReportCode = "reportCode";

    private String mapBugRemark = "bugRemark";

    private String mapUatResult = "uatResult";

    private String bugRemarkMsgTwo;

    private String bugRemarkMsgOne;

    private String uatResultMsg;

    private String sitBugMsg;

    private String regBugMsg;

    @Override
    public void execute(JobExecutionContext context) {
        // 设置msg
        bugRemarkMsgTwo = BaseConstants.getConstantsCodeMap().get("reportMsg.bugRemarkMsgTwo");
        bugRemarkMsgOne = BaseConstants.getConstantsCodeMap().get("reportMsg.bugRemarkMsgOne");
        uatResultMsg = BaseConstants.getConstantsCodeMap().get("reportMsg.uatResultMsg");
        sitBugMsg = "\n" + BaseConstants.getConstantsCodeMap().get("reportMsg.sitBugMsg") + "\n";
        regBugMsg = "\n" + BaseConstants.getConstantsCodeMap().get("reportMsg.regBugMsg") + "\n";

        // 获得数据
        ApplicationContext applicationContext = QuartzUtil.getApplicaitonContext(context);
        // 上下文获取异常时，跳出
        if (applicationContext == null) {
            return;
        }

        JiraService jiraService = applicationContext.getBean(JiraService.class);
        ReportJiraMapper reportJiraMapper = applicationContext.getBean(ReportJiraMapper.class);
        IdGenerator idGenerator = applicationContext.getBean(IdGenerator.class);
        ReportInfoMapper reportInfoMapper = applicationContext.getBean(ReportInfoMapper.class);
        ReportTestLinkMapper reportTestLinkMapper = applicationContext.getBean(ReportTestLinkMapper.class);

        // 获取当前任务对应的reportCode
        String jobName = context.getJobDetail().getKey().getName();
        String reportCode = jobName.substring(jobName.indexOf('_') + 1, jobName.length());

        // 获取当前任务对应TESTLINK信息
        ReportTestLink reportTestLink = new ReportTestLink();
        reportTestLink.setReportCode(reportCode);
        List<ReportTestLink> reportTestLinkList = reportTestLinkMapper.select(reportTestLink);

        // 查询JIRA数据
        if (reportTestLinkList != null && !reportTestLinkList.isEmpty()) {
            // 存储数据
            Map mapData = new HashMap();
            mapData.put(mapUatResult, "");
            mapData.put(mapBugRemark, "");
            for (ReportTestLink reportTestLink1 : reportTestLinkList) {
                // 整理更新report需要的数据和更新reportJira
                analysisData(reportCode, reportTestLink1.getVersionId(), mapData,  idGenerator, jiraService, reportJiraMapper, reportTestLinkMapper);
            }
            // 更新reportInfo
            updateReportInfo(reportCode, mapData, reportInfoMapper, reportTestLinkMapper);
        }
    }

    /**
     * 更新reportJira
     *
     * @param reportCode
     * @param versionId
     * @param mapData
     * @param jiraService
     * @param reportJiraMapper
     */
    private void analysisData(String reportCode, Long versionId, Map mapData, IdGenerator idGenerator,
                              JiraService jiraService, ReportJiraMapper reportJiraMapper, ReportTestLinkMapper reportTestLinkMapper) {
        // 删除旧数据，保证与jira同步
        Example example = new Example(ReportJira.class);
        example.createCriteria().andEqualTo(sqlReportCode, reportCode).andEqualTo("versionId", versionId);
        // 先提取再删除，提取目的是保存测试负责人
        List<ReportJira> reportJiraList = reportJiraMapper.selectByExample(example);
        Map mapTestLeader = new HashMap();
        if (reportJiraList != null && !reportJiraList.isEmpty()) {
            for (ReportJira reportJira : reportJiraList) {
                mapTestLeader.put(reportJira.getIssuesKey(), reportJira.getTestLeader());
            }
        }

        logger.info("==== JiraJob jira request data :==== {}", versionId);
        JiraInfo jiraInfo = jiraService.getOneInfoReVersion(versionId);
        String jiraInfoJson = GsonUtils.getInstance().toJson(jiraInfo);
        logger.info("==== JiraJob jira response data :==== {}", jiraInfoJson);

        reportJiraMapper.deleteByExample(example);
        if (jiraInfo != null && StringUtils.isNotBlank(jiraInfo.getProjectName()) && StringUtils.isNotBlank(jiraInfo.getVersionName())) {
            List<JiraIssues> jiraIssuesList = jiraInfo.getIssuesList();
            // 功能测试统计
            int countSitBug = 0;
            int countRetBug = 0;
            int countUatBug = 0;
            int totalBugCount = 0;
            StringBuilder bugRemarkSB = new StringBuilder();
            List<String> noCloseBugList = new ArrayList<>();
            // 设置UAT和BUGREMARK栏
            ReportTestLink reportTestLink = new ReportTestLink();
            reportTestLink.setVersionId(versionId);
            reportTestLink.setReportCode(reportCode);
            reportTestLink = reportTestLinkMapper.selectOne(reportTestLink);
            if (jiraIssuesList != null && !jiraIssuesList.isEmpty()) {

                for (JiraIssues jiraIssues : jiraIssuesList) {
                    if (jiraIssues.getTypeName().equalsIgnoreCase(BaseConstants.getConstantsCodeMap().get("jiraStatus.bug"))) {
                        // 为bug的时候统计bug类型，将bug方法bugRemark中
                        String discoveryStage = jiraIssues.getDiscovryStage();
                        String ret = BaseConstants.getConstantsCodeMap().get("bugType.reg");
                        String uat = BaseConstants.getConstantsCodeMap().get("bugType.uat");
                        if (discoveryStage.equalsIgnoreCase(ret)) {
                            countRetBug++;
                        } else if (discoveryStage.equalsIgnoreCase(uat)) {
                            countUatBug++;
                        } else {
                            countSitBug++;
                        }
                        // 拼接bugRemark
                        getBugRemark(noCloseBugList, jiraIssues);
                    } else {
                        // 非bug情况下，将数据更新到数据库中
                        insertReportJira(reportCode, jiraInfo, jiraIssues, versionId, mapTestLeader, idGenerator, reportJiraMapper);


                    }
                }
                // bug数量解析/SIT
                updateBugData(reportCode, versionId, countSitBug, "SIT", reportTestLinkMapper);
                // bug数量解析/RET
                updateBugData(reportCode, versionId, countRetBug, "RET", reportTestLinkMapper);

                totalBugCount = countSitBug + countRetBug + countUatBug;

                if (!noCloseBugList.isEmpty()) {
                    String bugRemarkMsgOneStr = MessageFormat.format(bugRemarkMsgOne,
                            reportTestLink.getTprjname(),
                            reportTestLink.getVersionName(),
                            totalBugCount,
                            noCloseBugList.size());
                    bugRemarkSB.append(bugRemarkMsgOneStr);
                    for (int i = 0; i < noCloseBugList.size(); i++) {
                        if (i == 5) {
                            break;
                        }
                        bugRemarkSB.append("\n" + (i + 1) + "." + noCloseBugList.get(i));
                    }
                    if (noCloseBugList.size() > 5) {
                        bugRemarkSB.append("\n...(还有" + (noCloseBugList.size() - 5) + "个Bug)");
                    }
                }
            }
            if (StringUtils.isBlank(bugRemarkSB.toString())) {
                String bugRemarkMsgTwoStr = MessageFormat.format(bugRemarkMsgTwo,
                        reportTestLink.getTprjname(),
                        reportTestLink.getVersionName(),
                        totalBugCount);
                bugRemarkSB.append(bugRemarkMsgTwoStr);
            }
            setUatAndBugRemark(bugRemarkSB, jiraInfo.getProjectName(), jiraInfo.getVersionName(), countUatBug, mapData);
        }
    }

    /**
     * 收集bug
     *
     * @param noCloseBugList
     * @param jiraIssues
     * @return
     */
    private void getBugRemark(List<String> noCloseBugList, JiraIssues jiraIssues) {
        StringBuilder bugRemarkSB = new StringBuilder();
        // 收集bug
        if (!jiraIssues.getIssuesStatu().equals(BaseConstants.getConstantsCodeMap().get("bugStatus.close"))) {
            bugRemarkSB.append(jiraIssues.getIssuesKey());
            String issuesName = " 【" + jiraIssues.getIssuesName() + "】";
            if (issuesName.length() > 50) {
                issuesName = issuesName.substring(0, 50) + "...";
            }
            bugRemarkSB.append(issuesName);
            bugRemarkSB.append(" 【" + jiraIssues.getIssuesStatu() + "】");
            noCloseBugList.add(bugRemarkSB.toString());

        }
    }


    private void insertReportJira(String reportCode, JiraInfo jiraInfo, JiraIssues jiraIssues, Long versionId, Map mapTestLeader,
                                                                                                                     IdGenerator idGenerator, ReportJiraMapper reportJiraMapper) {
        //ReportJira
        ReportJira entity = new ReportJira();
        entity.setReportCode(reportCode);
        entity.setVersionId(versionId);
        entity.setVersionName("【" + jiraInfo.getProjectName() + "】" + jiraInfo.getVersionName());
        entity.setVersionRemark(jiraInfo.getVersionDescription());
        entity.setIssuesKey(jiraIssues.getIssuesKey());
        entity.setIssuesName("【" + jiraIssues.getIssuesKey() + "】" + jiraIssues.getIssuesName());
        entity.setAssignee(jiraIssues.getReporter());
        if (mapTestLeader.get(jiraIssues.getIssuesKey()) != null) {
            entity.setTestLeader((String) mapTestLeader.get(jiraIssues.getIssuesKey()));
        } else {
            entity.setTestLeader("123");
        }

        entity.setIssuesStatus(jiraIssues.getIssuesStatu());
        entity.setId(idGenerator.nextId());
        // 设置更新人和时间
        entity.setCreateBy("JIRA");
        entity.setCreateTime(new Date());
        reportJiraMapper.insert(entity);
    }


    /**
     * bug数量解析
     *
     * @param versionId
     * @param countBug
     * @param type
     */
    private void updateBugData(String reportCode, Long versionId, int countBug, String type, ReportTestLinkMapper reportTestLinkMapper) {
        // 获取数据
        Example example = new Example(ReportTestLink.class);
        example.createCriteria().andEqualTo(sqlReportCode, reportCode).andEqualTo("versionId", versionId);
        ReportTestLink reportTestLink = new ReportTestLink();
        if ("SIT".equalsIgnoreCase(type)) {
            reportTestLink.setSitBugCount((long) countBug);
        } else {
            reportTestLink.setRegBugCount((long) countBug);
        }
        reportTestLinkMapper.updateByExampleSelective(reportTestLink, example);


    }

    /**
     * 设置UAT和BUGREMARK栏
     *
     * @param bugRemarkSB
     * @param versionName
     * @param countUatBug
     * @param mapData
     */
    private void setUatAndBugRemark(StringBuilder bugRemarkSB, String projectName, String versionName, int countUatBug, Map mapData) {
        StringBuilder bugRemarkSBNew = new StringBuilder((String) mapData.get(mapBugRemark));
        if (StringUtils.isNotBlank(bugRemarkSBNew.toString())) {
            bugRemarkSBNew.append("\n\n");
        }
        bugRemarkSBNew.append(bugRemarkSB);
        mapData.put(mapBugRemark, bugRemarkSBNew.toString());

        String uatResultMsgStr = MessageFormat.format(uatResultMsg, projectName, versionName, countUatBug);

        StringBuilder uatResultSBNew = new StringBuilder((String) mapData.get(mapUatResult));
        if (StringUtils.isNotBlank(uatResultSBNew.toString())) {
            uatResultSBNew.append("\n");
        }
        uatResultSBNew.append(uatResultMsgStr);
        mapData.put(mapUatResult, uatResultSBNew.toString());
    }

    /**
     * 更新reportInfo
     *
     * @param
     */
    private void updateReportInfo(String reportCode, Map mapData, ReportInfoMapper reportInfoMapper, ReportTestLinkMapper reportTestLinkMapper) {
        String uatResult = (String) mapData.get(mapUatResult);
        String bugRemark = (String) mapData.get(mapBugRemark);
        // 更新reportInfo的BUG概述
        ReportInfo entity = new ReportInfo();
        // 设置ReportInfo数据
        QuartzUtil.setReportInfo(reportCode, entity, sitBugMsg, regBugMsg, reportTestLinkMapper);
        // 更新条件reportCode
        Example example = new Example(ReportInfo.class);
        example.createCriteria().andEqualTo(sqlReportCode, reportCode);

        // 设置更新人和时间
        entity.setUpdateBy("JIRA");
        entity.setUatResult(uatResult);
        entity.setBugRemark(bugRemark);

        // 更新条件reportCode
        reportInfoMapper.updateByExampleSelective(entity, example);

    }

}
